package org.edu.modules.kwgl.controller;

import java.io.Console;
import java.io.IOException;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import net.sf.saxon.expr.instruct.ForEach;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.edu.common.api.vo.Result;
import org.edu.common.system.base.controller.BaseController;
import org.edu.common.system.query.QueryGenerator;
import org.edu.modules.kwgl.api.CommonApi;
import org.edu.modules.kwgl.api.IVeJwJxzyFeignClientService;
import org.edu.modules.kwgl.entity.*;
import org.edu.modules.kwgl.service.IVeJwKaoshiChaibanService;
import org.edu.modules.kwgl.service.IVeJwKaoshiService;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.edu.modules.kwgl.service.IVeJwKsJiankaoService;
import org.edu.modules.kwgl.service.IVeJwKssjdService;
import org.edu.modules.kwgl.utils.CommonAipUtils;
import org.edu.modules.kwgl.utils.ExcelUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.edu.common.aspect.annotation.AutoLog;

 /**
 * @Description: 考试信息
 * @Author: jeecg-boot
 * @Date:   2021-05-07
 * @Version: V1.0
 */
@Api(tags="考试信息")
@RestController
@RequestMapping("/kwgl/veJwKaoshi")
@Slf4j
public class VeJwKaoshiController extends BaseController<VeJwKaoshi, IVeJwKaoshiService> {
	@Autowired
	private IVeJwKaoshiService veJwKaoshiService;

	@Autowired
	 private IVeJwKsJiankaoService veJwKsJiankaoService;

	 @Autowired
	 IVeJwJxzyFeignClientService veJwJxzyFeignClientService;

	 @Autowired
	 CommonApi commonApi;

	 @Autowired
	 private IVeJwKssjdService veJwKssjdService;

	 @Autowired
	 private IVeJwKaoshiChaibanService kaoshiChaibanService;


	/**
	 * 分页列表查询
	 *
	 * @param veJwKaoshi
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@AutoLog(value = "考试信息-分页列表查询")
	@ApiOperation(value="考试信息-分页列表查询", notes="考试信息-分页列表查询")
	@GetMapping(value = "/list")
	public Result<?> queryPageList(VeJwKaoshi veJwKaoshi,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<VeJwKaoshi> queryWrapper = QueryGenerator.initQueryWrapper(veJwKaoshi, req.getParameterMap());
		queryWrapper.orderByDesc("createTime");
		Page<VeJwKaoshi> page = new Page<VeJwKaoshi>(pageNo, pageSize);
		IPage<VeJwKaoshi> pageList = veJwKaoshiService.page(page, queryWrapper);

		List<String> list;
		for (VeJwKaoshi item:pageList.getRecords()){
			list=veJwKsJiankaoService.get2teacheridByKsid(item.getId());
			item.setJiankao(list.get(0));
			item.setXunkao(list.get(1));
			item.setKsfs(veJwJxzyFeignClientService.getKcKsfsById(item.getKcid()));
		}

		return Result.ok(pageList);
	}

	 /**
	  * 分页列表查询
	  *
	  * @param veJwKaoshi
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @AutoLog(value = "考试拆班信息-分页列表查询")
	 @ApiOperation(value="考试拆班信息-分页列表查询", notes="考试拆班信息-分页列表查询")
	 @GetMapping(value = "/cb/list")
	 public Result<?> queryChaibanPageList(VeJwKaoshi veJwKaoshi,
									@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
									@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
									HttpServletRequest req) {

		 VeJwKaoshi kaoshi = veJwKaoshiService.getBySemidAndKcidAndBjid(veJwKaoshi.getSemid(), veJwKaoshi.getKcid(), veJwKaoshi.getBjid());
		 int count = 0;
		 if(kaoshi != null){
			 LambdaQueryWrapper<VeJwKaoshiChaiban> cbWrapper = new LambdaQueryWrapper<>();
			 cbWrapper.eq(VeJwKaoshiChaiban::getKsid, kaoshi.getId());
			 count = kaoshiChaibanService.count(cbWrapper);
		 }

		 List<VeJwKaoshi> ksList = Lists.newArrayList();
		 if(count == 0 && kaoshi != null){
			 ksList.add(kaoshi);
		 } else {
			 for(int i = 0; i < count; i++){
				 ksList.add(kaoshi);
			 }
		 }
		 List<String> list;
		 for (VeJwKaoshi item : ksList){
			 list=veJwKsJiankaoService.get2teacheridByKsid(item.getId());
			 item.setJiankao(list.get(0));
			 item.setXunkao(list.get(1));
			 item.setKsfs(veJwJxzyFeignClientService.getKcKsfsById(item.getKcid()));
		 }
		 IPage<VeJwKaoshi> pageList = new Page<>();
		 pageList.setRecords(ksList);

		 return Result.ok(pageList);
	 }

	 /**
	  * 成绩录入-分页列表查询
	  *
	  * @param veJwKaoshi
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @AutoLog(value = "考试信息-成绩录入-分页列表查询")
	 @ApiOperation(value="考试信息-成绩录入-分页列表查询", notes="考试信息-成绩录入-分页列表查询")
	 @GetMapping(value = "/lrlist")
	 public Result<?> queryPagelrList(VeJwKaoshi veJwKaoshi,
									@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
									@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
									HttpServletRequest req) {
		 QueryWrapper<VeJwKaoshi> queryWrapper = QueryGenerator.initQueryWrapper(veJwKaoshi, req.getParameterMap());
		 queryWrapper.orderByDesc("createTime");
		 //筛选考试时间已过且已发布的考试信息
		 queryWrapper.lt("KSRQ",new Date());
		 queryWrapper.eq("isPublish",1);
		 Page<VeJwKaoshi> page = new Page<VeJwKaoshi>(pageNo, pageSize);
		 IPage<VeJwKaoshi> pageList = veJwKaoshiService.page(page, queryWrapper);
		 for (VeJwKaoshi item:pageList.getRecords()){
			 item.setKsfs(veJwJxzyFeignClientService.getKcKsfsById(item.getKcid()));
		 }
		 return Result.ok(pageList);
	 }
	
	/**
	 *   添加
	 *
	 * @param veJwKaoshi
	 * @return
	 */
	@AutoLog(value = "考试信息-添加")
	@ApiOperation(value="考试信息-添加", notes="考试信息-添加")
	@PostMapping(value = "/add")
	public Result<?> add(@RequestBody VeJwKaoshi veJwKaoshi) {

		VeJwKaoshi kaoshi = veJwKaoshiService.getBySemidAndKcidAndBjid(veJwKaoshi.getSemid(), veJwKaoshi.getKcid(), veJwKaoshi.getBjid());
		if(kaoshi != null){
			return Result.error("该班级的该课程已安排考试");
		}
		String kcmc = veJwJxzyFeignClientService.getKcNameById(veJwKaoshi.getKcid());
		Result<JSONObject> result = veJwJxzyFeignClientService.getJsById(veJwKaoshi.getJsid());
		String jsmc = result.getResult().getString("jsmc");
		Long l=System.currentTimeMillis();
		Integer now=new Long(l).intValue();
		//todo 考试名称设置 +"-"+jsmc+"-补考"
		veJwKaoshi.setName(kcmc+"-"+veJwKaoshi.getKsrq());
		veJwKaoshi.setCreatetime(now);
		VeJwKssjd veJwKssjd = veJwKssjdService.getById(veJwKaoshi.getKssjdid());
		if(veJwKssjd!=null){
			veJwKaoshi.setKsrqsj(veJwKssjd.getStarttime()+"~"+veJwKssjd.getEndtime());
		}
		veJwKaoshiService.save(veJwKaoshi);

		// 设置了每班考试人数 说明要拆班
		if(veJwKaoshi.getMaxNumber() != null){
			// 如果每班考试人数不等于班级总人数，说明拆班
			if(!veJwKaoshi.getMaxNumber().equals(veJwKaoshi.getBjNumber())){
				// 拆班信息
				List<VeJwKaoshiChaiban> kscbList = Lists.newArrayList();
				int total = veJwKaoshi.getBjNumber();
				while(total > 0){
					VeJwKaoshiChaiban temp = new VeJwKaoshiChaiban();
					temp.setKsid(veJwKaoshi.getId());
					temp.setXzbid(veJwKaoshi.getBjid());
					temp.setNumber(veJwKaoshi.getMaxNumber());

					kscbList.add(temp);
					total -= veJwKaoshi.getMaxNumber();
				}
				kaoshiChaibanService.saveBatch(kscbList);
			}
		}

		return Result.ok("添加成功！");
	}
	
	/**
	 *  编辑
	 *
	 * @param veJwKaoshi
	 * @return
	 */
	@AutoLog(value = "考试信息-编辑")
	@ApiOperation(value="考试信息-编辑", notes="考试信息-编辑")
	@PutMapping(value = "/edit")
	public Result<?> edit(@RequestBody VeJwKaoshi veJwKaoshi) {
		VeJwKssjd veJwKssjd = veJwKssjdService.getById(veJwKaoshi.getKssjdid());
		if(veJwKssjd!=null){
			veJwKaoshi.setKsrqsj(veJwKssjd.getStarttime()+"~"+veJwKssjd.getEndtime());
		}
		veJwKaoshiService.updateById(veJwKaoshi);
		return Result.ok("编辑成功!");
	}
	
	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "考试信息-通过id删除")
	@ApiOperation(value="考试信息-通过id删除", notes="考试信息-通过id删除")
	@DeleteMapping(value = "/delete")
	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
		veJwKaoshiService.removeById(id);
		return Result.ok("删除成功!");
	}
	
	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "考试信息-批量删除")
	@ApiOperation(value="考试信息-批量删除", notes="考试信息-批量删除")
	@DeleteMapping(value = "/deleteBatch")
	public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.veJwKaoshiService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.ok("批量删除成功!");
	}
	
	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "考试信息-通过id查询")
	@ApiOperation(value="考试信息-通过id查询", notes="考试信息-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
		VeJwKaoshi veJwKaoshi = veJwKaoshiService.getById(id);
		if(veJwKaoshi==null) {
			return Result.error("未找到对应数据");
		}
		return Result.ok(veJwKaoshi);
	}

    /**
    * 导出excel
    *
    * @param request
    * @param veJwKaoshi
    */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, VeJwKaoshi veJwKaoshi) {
        return super.exportXls(request, veJwKaoshi, VeJwKaoshi.class, "考试信息");
    }

    /**
      * 通过excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
		for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
			MultipartFile file = entity.getValue();// 获取上传文件对象
			try {
				int error = 0;
				int success = 0;
				int count = 0;
				Workbook workbook = null;
				if (file.getOriginalFilename().toLowerCase().endsWith("xlsx")) {
					workbook = new XSSFWorkbook(file.getInputStream());
				} else if (file.getOriginalFilename().toLowerCase().endsWith("xls")) {
					workbook = new HSSFWorkbook(new POIFSFileSystem(file.getInputStream()));
				}

				Sheet sheet = workbook.getSheetAt(0);

				Map<String,JSONObject> teacherMap = new HashMap<>();
				Map<String,JSONObject> banjiMap = new HashMap<>();
				Map<Integer,JSONObject> specMap = new HashMap<>();
				Map<String,JSONObject> xiaoMap = new HashMap<>();
				Map<String,Integer> kcidMap = new HashMap<>();


				Map<String,Integer> jzwMap = new HashMap<>();
				Map<String,Integer> jsMap = new HashMap<>();

				Map<String,Integer> xiaoquMap = CommonAipUtils.getXiaoquNameId();

				//根据模板，从第3行开始才是正式数据
				for (int i = 2; i <= sheet.getLastRowNum(); i++) {
					VeJwKaoshi item=new VeJwKaoshi();
					count++;
					Row row = sheet.getRow(i);
					int cell = 0;
					boolean isError = false;
					//科目
					String km=ExcelUtils.GetStringValue(row.getCell(cell++));
					//考场
					String kc=ExcelUtils.GetStringValue(row.getCell(cell++));
					//班级
					String bj=ExcelUtils.GetStringValue(row.getCell(cell++));
					//时间
					String sj=ExcelUtils.GetStringValue(row.getCell(cell++));
					//人数
					String rs=ExcelUtils.GetStringValue(row.getCell(cell++));
					try {
						if(StringUtils.isNotEmpty(rs)){
							item.setNumber(Integer.valueOf(rs));
						}
					}catch (Exception e){

					}
					//教师工号
					String gh=ExcelUtils.GetStringValue(row.getCell(cell++));
					//验证课程
					if(StringUtils.isEmpty(km) || StringUtils.isEmpty(kc) || StringUtils.isEmpty(bj) || StringUtils.isEmpty(sj) || StringUtils.isEmpty(gh)){
						error++;
						continue;
					}
					if(!sj.contains("_")){
						error++;
						continue;
					}

//					考试时间
					String[] timeStr= sj.split("_");
					item.setKsrq(timeStr[0]);
					item.setKsrqsj(timeStr[1]);
					item.setKssjdid(0);

//					验证控课程
					if(!kcidMap.containsKey(km)){
						Integer kcid = veJwJxzyFeignClientService.getIdByName(km);
						if(kcid==null){
							error++;
							continue;
						}
						kcidMap.put(km,kcid);
					}
					item.setKcid(kcidMap.get(km));
//					验证考场
					String[] kcStrList= kc.trim().split("-");
					if(kcStrList.length != 3){
						error++;
						continue;
					}

					if(!xiaoquMap.containsKey(kcStrList[0])){
						error++;
						continue;
					}
					item.setCampusid(xiaoquMap.get(kcStrList[0]));

					try {
//						验证教学楼，验证教室
						if(!jzwMap.containsKey(kcStrList[0] + "-" +kcStrList[1])){
							List<JwJianzhu> jzList = veJwJxzyFeignClientService.getJzListByName(kcStrList[1]);
							if(jzList != null){
								for(JwJianzhu jzItem:jzList){
									if(jzItem.getCampusid() == item.getCampusid()){
										jzwMap.put(kcStrList[0] + "-" +kcStrList[1],jzItem.getId());
									}
								}
							}
						}
						if(!jzwMap.containsKey(kcStrList[0] + "-" +kcStrList[1])){
							error++;
							continue;
						}
						item.setJzid(jzwMap.get(kcStrList[0] + "-" +kcStrList[1]));

//					验证教室
						if(!jsMap.containsKey(kcStrList[0] + "-" +kcStrList[1] + "-" +kcStrList[2])){
							List<JwJiaoshi> jsList = veJwJxzyFeignClientService.getJsListByName(kcStrList[2]);
							if(jsList != null){
								for(JwJiaoshi jsItem:jsList){
									if(jsItem.getCampusid() == item.getCampusid() && jsItem.getJzid() == item.getJzid()){
										jsMap.put(kcStrList[0] + "-" +kcStrList[1] + "-" +kcStrList[2],jsItem.getId());
									}
								}
							}
						}
						if(!jsMap.containsKey(kcStrList[0] + "-" +kcStrList[1] + "-" +kcStrList[2])){
							error++;
							continue;
						}
						item.setJsid(jsMap.get(kcStrList[0] + "-" +kcStrList[1] + "-" +kcStrList[2]));
					}catch (Exception e){
						error++;
						continue;
					}


					if(!banjiMap.containsKey(bj)){
//					验证班级
						JSONObject bjObj =  CommonAipUtils.getBanjiByName(bj);
						if(bjObj==null){
							error++;
							continue;
						}
						banjiMap.put(bj,bjObj);
					}
					JSONObject banji = banjiMap.get(bj);
					item.setSpecid(banji.getInteger("spec_id"));
					item.setGradeid(banji.getInteger("grade_id"));


//					验证专业
					if(!specMap.containsKey(item.getSpecid())){
						JSONObject temp =CommonAipUtils.getZyObjById(item.getSpecid());
						if(temp==null){
							error++;
							continue;
						}
						specMap.put(item.getSpecid(),temp);
					}
					JSONObject zy =specMap.get(item.getSpecid());
					item.setFalid(zy.getInteger("falid"));
					try {
						item.setXzid(zy.getInteger("xz"));
					}catch (Exception e){

					}

//					验证监控老师
					if(!teacherMap.containsKey(gh)){
						//获取监控老师信息
						Result<JSONObject>	result=commonApi.queryTeacherByGH(CommonApi.COMMON_TOKEN_KEY, gh);
						JSONObject jsonObject =result.getResult();
						if(jsonObject==null){
							error++;
							continue;
						}
						teacherMap.put(gh,jsonObject);
					}

					JSONObject teacher=teacherMap.get(gh);

					//监考老师
					String jkls=ExcelUtils.GetStringValue(row.getCell(cell++));
					isError = jkls == null;
					if (isError) {
//						对应身份证用户已存在
						error++;
					}else {
						success++;
						veJwKaoshiService.save(item);
						VeJwKsJiankao veJwKsJiankao=new VeJwKsJiankao();
						veJwKsJiankao.setKsid(item.getId());
						veJwKsJiankao.setTeacherid(teacher.getInteger("id"));
						veJwKsJiankao.setType(1);
						veJwKsJiankaoService.save(veJwKsJiankao);
					}
				}
				String msg = "文件导入成功！数据行数：" + count + ", 成功" + success + "条" + (error > 0 ? ",失败" + error + "条" : "。");
//				return Result.error("文件导入失败:处理失败" );
				return Result.ok(msg);
			} catch (Exception e) {
				log.error(e.getMessage(), e);
				return Result.error("文件导入失败:" + e.getMessage());
			} finally {
				try {
					file.getInputStream().close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return Result.error("文件导入失败！");
    }

	 /**
	  * 批量启用/禁用
	  *
	  * @param ids
	  * @param status
	  * @return
	  */
	 @AutoLog(value = "教室信息表-批量启用/禁用")
	 @ApiOperation(value="教室信息表-批量启用/禁用", notes="教室信息表-批量启用/禁用")
	 @GetMapping(value = "/updateStatusBatch")
	 public Result<?> updateStatusBatch(@RequestParam(name="ids",required=true) String ids,
										@RequestParam(name="status",required = true)int status) {
		 veJwKaoshiService.updateStatusByIds(ids,status);
		 return Result.ok("更新状态成功!");
	 }



	 /**
	  * 发布/取消发布
	  *
	  * @param id
	  * @param status
	  * @return
	  */
	 @AutoLog(value = "考试信息表-发布/取消发布")
	 @ApiOperation(value="考试信息表-发布/取消发布", notes="考试信息表-发布/取消发布")
	 @GetMapping(value = "/changePublishById")
	 public Result<?> changePublishById(@RequestParam(name="id",required=true) int id,
										@RequestParam(name="status",required = true)int status) {
		//判断是否启用
		 if(status==1){
			 if(veJwKaoshiService.getById(id).getStatus()==0){
				 return Result.error("该清考信息还未启用！");
			 }
		 }
		 veJwKaoshiService.changePublishById(id, status);
		 if (status == 1) {
			 return Result.ok("发布成功!");
		 }
		 return Result.ok("取消发布成功!");
	 }


	 /**
	  * 根据课程id查询是否存在对应补考
	  *
	  * @param kcid
	  * @return
	  */
	 @AutoLog(value = "考试信息表-根据课程id查询是否存在对应考试")
	 @ApiOperation(value="考试信息表-根据课程id查询是否存在对应考试", notes="考试信息表-根据课程id查询是否存在对应考试")
	 @GetMapping(value = "/queryByKcid")
	 public Result<?> queryByKcid(@RequestParam(name="kcid",required=true) int kcid) {
		 VeJwKaoshi kaoshi = veJwKaoshiService.getByKcid(kcid);
		 if(kaoshi==null){
			 return Result.error("暂无此课程的考试信息！");
		 }
		 return Result.ok(kaoshi);
	 }
}
